package com.avic.map.controller;

import com.avic.map.common.constant.LocalResourceConstant;
import com.avic.map.common.constant.SystemLogConstant;
import com.avic.map.common.constant.UserConstant;
import com.avic.map.common.convertor.CarResourceConvertor;
import com.avic.map.common.util.AssertUtil;
import com.avic.map.common.util.FileUploadUtil;
import com.avic.map.common.util.ex.BizErrorCode;
import com.avic.map.common.util.lang.BaseResponse;
import com.avic.map.common.util.lang.ServiceCallBack;
import com.avic.map.controller.request.CreateCarResourceReq;
import com.avic.map.controller.request.GetCarResourceListReq;
import com.avic.map.controller.request.UpdateCarResourceReq;
import com.avic.map.controller.result.BaseCreateResourceRes;
import com.avic.map.controller.result.GetCarResourceListRes;
import com.avic.map.dal.condition.PageQueryCarResourceListCondition;
import com.avic.map.dal.model.CarResource;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestHeader;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.util.List;


@Slf4j
@RestController
@RequestMapping("resource/car")
@Api(tags = "车辆资源", description = "分页查询车辆资源列表&创建车辆资源&修改车辆资源&删除车辆资源")
public class CarResourceController extends AbstractFacadeImpl {

    @ApiOperation(value = "分页查询车辆资源列表")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "getCarResourceListReq", required = true, dataType = "GetCarResourceListReq")
    })
    @PostMapping("list")
    public GetCarResourceListRes getCarResourceList(@RequestBody GetCarResourceListReq getCarResourceListReq) {
        final GetCarResourceListRes result = new GetCarResourceListRes();
        return serviceExecuteTemplate.executeService(result, new ServiceCallBack() {
            @Override
            public void check() throws Exception {
            }

            @Override
            public void doService() throws Exception {
                PageQueryCarResourceListCondition pageQueryCarResourceListCondition = new PageQueryCarResourceListCondition(
                        getCarResourceListReq.getCurrentPage(), getCarResourceListReq.getPageSize()
                );
                pageQueryCarResourceListCondition.setCarName(getCarResourceListReq.getCarName());
                pageQueryCarResourceListCondition.setCarNumber(getCarResourceListReq.getCarNumber());
                pageQueryCarResourceListCondition.setFleetName(getCarResourceListReq.getFleetName());

                List<CarResource> carResources = carResourceService.itemList(pageQueryCarResourceListCondition);

                result.setItemList(CarResourceConvertor.CarResourcesToCarResourceListInfo(carResources, commonProperties.getViewFilePrefix()));
                result.setItemTotal(carResourceService.queryRecordsTotal(pageQueryCarResourceListCondition));
                result.setSuccess(true);
            }
        });
    }

    @ApiOperation(value = "创建车辆资源")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "createCarResourceReq", required = true, dataType = "CreateCarResourceReq")
    })
    @PostMapping
    public BaseCreateResourceRes createCarResource(@RequestBody CreateCarResourceReq createCarResourceReq,
                                                   @RequestHeader(value = UserConstant.HEADER_CURRENT_USER_ID_KEY, required = false) String currentUserId) {
        final BaseCreateResourceRes result = new BaseCreateResourceRes();
        return serviceExecuteTemplate.executeService(result, new ServiceCallBack() {
            @Override
            public void check() throws Exception {
                AssertUtil.isNotBlank(createCarResourceReq.getCarNumber(), "carName is blank");

            }

            @Override
            public void doService() throws Exception {
                // 转换参数
                CarResource carResource = new CarResource();
                carResource.setCarNumber(createCarResourceReq.getCarNumber());
                carResource.setCarType(createCarResourceReq.getCarType());
                carResource.setFleetId(createCarResourceReq.getFleetId());
                carResource.setDriveForm(createCarResourceReq.getDriveForm());
                carResource.setFoamFireExtinguisherModel(createCarResourceReq.getFoamFireExtinguisherModel());
                carResource.setChassisModel(createCarResourceReq.getChassisModel());
                carResource.setSelfWeight(createCarResourceReq.getSelfWeight());
                carResource.setBoomModel(createCarResourceReq.getBoomModel());
                carResource.setCarWater(createCarResourceReq.getCarWater());
                carResource.setPullArmHookModel(createCarResourceReq.getPullArmHookModel());
                carResource.setCarFoam(createCarResourceReq.getCarFoam());
                carResource.setCarCrew(createCarResourceReq.getCarCrew());
                carResource.setCarDimensions(createCarResourceReq.getCarDimensions());
                carResource.setPumpModel(createCarResourceReq.getPumpModel());
                carResource.setPumpFlow(createCarResourceReq.getPumpFlow());
                carResource.setWaterAbsorptionFlow(createCarResourceReq.getWaterAbsorptionFlow());
                carResource.setWaterCannonModel(createCarResourceReq.getWaterCannonModel());
                carResource.setWaterSupply(createCarResourceReq.getWaterSupply());
                carResource.setWaterCannonFlow(createCarResourceReq.getWaterCannonFlow());
                carResource.setLoadingWaterVolume(createCarResourceReq.getLoadingWaterVolume());
                carResource.setCarRange(createCarResourceReq.getCarRange());
                carResource.setCarRemark(createCarResourceReq.getCarRemark());

                result.setItemId(String.valueOf(carResourceService.create(carResource)));

                LocalResourceConstant.CAR_STATE_DB_MAP.put(createCarResourceReq.getCarNumber(), carResource);

                // 新建系统日志
                systemServiceFeignService.createSystemLog(
                        String.format(SystemLogConstant.CREATE_CAR_RESOURCE, result.getItemId(),
                                objectMapper.writeValueAsString(createCarResourceReq)), currentUserId);
                result.setSuccess(true);
            }
        });
    }

    @ApiOperation(value = "上传车辆图片接口")
    @PostMapping("upload/image/{carId}")
    public BaseCreateResourceRes uploadCarImage(@PathVariable("carId") int carId, @RequestParam("carImage") MultipartFile multipartFile,
                                                @RequestHeader(value = UserConstant.HEADER_CURRENT_USER_ID_KEY, required = false) String currentUserId) {
        final BaseCreateResourceRes result = new BaseCreateResourceRes();
        return serviceExecuteTemplate.executeService(result, new ServiceCallBack() {
            @Override
            public void check() throws Exception {
                AssertUtil.isTrue(null != multipartFile, BizErrorCode.PARAM_ERROR, "上传的文件不能为空");
                AssertUtil.isImage(multipartFile.getInputStream(), BizErrorCode.PARAM_ERROR);
                AssertUtil.isTrue(0 != carId, BizErrorCode.PARAM_ERROR, "车辆资源ID不能等于零");
            }

            @Override
            public void doService() throws Exception {
                CarResource carResource = carResourceService.queryCarResourceById(carId);
                AssertUtil.isNotNull(carResource, BizErrorCode.PARAM_ERROR, "更改的资源不存在");
                String visitUrl = fileUploadUtil.writeUploadFile(multipartFile, FileUploadUtil.MAP_CAR_IMAGE_MODULE);
                log.info("上传图片成功，获取到图片访问路径为 {}", visitUrl);

                carResourceService.updateCarImagePath(visitUrl, carId);

                try {
                    if (StringUtils.isNotBlank(carResource.getCarImagePath())) {
                        log.info("删除车辆以前的旧图片, {}", carResource.getCarImagePath());

                        File file = new File(commonProperties.getUploadLocation() + carResource.getCarImagePath());
                        if (file.exists() && file.isFile()) {
                            file.delete();
                        }
                    }
                } catch (Exception e) {
                    log.warn("删除图片失败 {}", commonProperties.getUploadLocation() + carResource.getCarImagePath());
                }

                //更新缓存
                carResource.setCarImagePath(commonProperties.getViewFilePrefix() + visitUrl);
                LocalResourceConstant.CAR_STATE_DB_MAP.put(carResource.getCarNumber(), carResource);

                // 新建系统日志
                systemServiceFeignService.createSystemLog(
                        String.format(SystemLogConstant.UPLOAD_CAR_IMAGE_RESOURCE, visitUrl, carResource.getCarNumber()), currentUserId);

                result.setItemId(commonProperties.getViewFilePrefix() + visitUrl);
                result.setSuccess(true);
            }
        });
    }


    @ApiOperation(value = "修改车辆资源")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "updateCarResourceReq", required = true, dataType = "UpdateCarResourceReq")
    })
    @PutMapping
    public BaseResponse updateCarResource(@RequestBody UpdateCarResourceReq updateCarResourceReq,
                                          @RequestHeader(value = UserConstant.HEADER_CURRENT_USER_ID_KEY, required = false) String currentUserId) {
        final BaseResponse result = new BaseResponse();
        return serviceExecuteTemplate.executeService(result, new ServiceCallBack() {
            @Override
            public void check() throws Exception {
                AssertUtil.isTrue(updateCarResourceReq.getItemId() != 0, BizErrorCode.PARAM_ERROR, "itemId is blank");
                AssertUtil.isNotBlank(updateCarResourceReq.getCarNumber(), "carNumber is blank");

            }

            @Override
            public void doService() throws Exception {
                // 请求参数转换
                CarResource carResource = new CarResource();
                carResource.setCarNumber(updateCarResourceReq.getCarNumber());
                carResource.setCarType(updateCarResourceReq.getCarType());
                carResource.setFleetId(updateCarResourceReq.getFleetId());
                carResource.setDriveForm(updateCarResourceReq.getDriveForm());
                carResource.setFoamFireExtinguisherModel(updateCarResourceReq.getFoamFireExtinguisherModel());
                carResource.setChassisModel(updateCarResourceReq.getChassisModel());
                carResource.setSelfWeight(updateCarResourceReq.getSelfWeight());
                carResource.setBoomModel(updateCarResourceReq.getBoomModel());
                carResource.setCarWater(updateCarResourceReq.getCarWater());
                carResource.setPullArmHookModel(updateCarResourceReq.getPullArmHookModel());
                carResource.setCarFoam(updateCarResourceReq.getCarFoam());
                carResource.setCarCrew(updateCarResourceReq.getCarCrew());
                carResource.setCarDimensions(updateCarResourceReq.getCarDimensions());
                carResource.setPumpModel(updateCarResourceReq.getPumpModel());
                carResource.setPumpFlow(updateCarResourceReq.getPumpFlow());
                carResource.setWaterAbsorptionFlow(updateCarResourceReq.getWaterAbsorptionFlow());
                carResource.setWaterCannonModel(updateCarResourceReq.getWaterCannonModel());
                carResource.setWaterSupply(updateCarResourceReq.getWaterSupply());
                carResource.setWaterCannonFlow(updateCarResourceReq.getWaterCannonFlow());
                carResource.setLoadingWaterVolume(updateCarResourceReq.getLoadingWaterVolume());
                carResource.setCarRange(updateCarResourceReq.getCarRange());
                carResource.setCarRemark(updateCarResourceReq.getCarRemark());
                carResource.setId(updateCarResourceReq.getItemId());

                carResourceService.update(carResource);

                // 更新缓存
                CarResource dbCarResource = carResourceService.queryCarResourceById(updateCarResourceReq.getItemId());
                LocalResourceConstant.CAR_STATE_DB_MAP.put(updateCarResourceReq.getCarNumber(), dbCarResource);
                // 新建系统日志
                systemServiceFeignService.createSystemLog(
                        String.format(SystemLogConstant.UPDATE_CAR_RESOURCE, updateCarResourceReq.getItemId(),
                                objectMapper.writeValueAsString(updateCarResourceReq)), currentUserId);
                result.setSuccess(true);
            }
        });
    }

    @ApiOperation(value = "删除车辆资源")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "itemId", paramType = "path", value = "资源ID", required = true)
    })
    @DeleteMapping("/{itemId}")
    public BaseResponse deleteCarResource(@PathVariable("itemId") int itemId,
                                          @RequestHeader(value = UserConstant.HEADER_CURRENT_USER_ID_KEY, required = false) String currentUserId) {
        final BaseResponse result = new BaseResponse();
        return serviceExecuteTemplate.executeService(result, new ServiceCallBack() {
            @Override
            public void check() throws Exception {
                AssertUtil.isTrue(itemId > 0, BizErrorCode.PARAM_ERROR, "数据ID大于零");

            }

            @Override
            public void doService() throws Exception {
                CarResource carResource = carResourceService.queryCarResourceById(itemId);
                AssertUtil.isNotNull(carResource, BizErrorCode.PARAM_ERROR, "删除的资源不存在");

                carResourceService.delete(itemId);

                // 删除缓存数据
                LocalResourceConstant.CAR_STATE_DB_MAP.remove(carResource.getCarNumber());

                // 新建系统日志
                systemServiceFeignService.createSystemLog(
                        String.format(SystemLogConstant.DELETE_CAR_RESOURCE, itemId), currentUserId);
                result.setSuccess(true);
            }
        });
    }
}
